import { keywordCompare } from '@gnlab/utils'
import { useObservable } from '@gnlab/utils/env-react/rx'
import useUIMemory from '@/logics/memory'
import services from '@/services'
import { stringifyWord } from '@/services/common/definition'
import type { Words, WordsGroup } from '@/services/resources/words-library'

export function useWordsList() {
  const [wordsList, setWordsList] = useState<Words[] | null>(null)
  const isLoading = wordsList === null
  const load = useCallback(() => {
    void services.resources.wordsLibrary.load().then(setWordsList)
  }, [])
  useEffect(() => load(), [load])
  useObservable(services.resources.wordsLibrary.updated, () => load(), [load]) // 话术库或分组有更新时重新加载

  return {
    wordsList,
    isLoading,
    reload: load,
  }
}

export function useWordsGroups() {
  const [groups, setGroups] = useState<WordsGroup[]>([])
  const load = useCallback(() => {
    void services.resources.wordsLibrary.loadGroups().then(setGroups)
  }, [])
  useEffect(() => void load(), [load])
  useObservable(services.resources.wordsLibrary.updated, () => load(), [load]) // 话术库或分组有更新时重新加载
  return {
    groups,
    reload: load,
  }
}

export function useFilter(
  allWordsList: Words[] | null,
  allGroups: WordsGroup[],
  reload: () => void,
) {
  /**
   * 筛选条件
   */
  const [showGlobal, rawSetShowGlobal] = useUIMemory<boolean>(
    'words-library-tab-show-global',
    false,
  )
  const setShowGlobal = useCallback(
    (showGlobal: boolean) => {
      rawSetShowGlobal(showGlobal)
      setFilterGroupId('all')
      setFilterKeyword('')
      reload() // 切换标签时重新加载最新的话术库
    },
    [rawSetShowGlobal, reload],
  )

  // number: 指定分组话术库 '': 未分组话术库 'all: 所有话术库
  const [filterGroupId, setFilterGroupId] = useState<number | '' | 'all'>('all')

  const [filterKeyword, setFilterKeyword] = useState('')

  /**
   * 过滤数据
   */
  const groups = useMemo(
    () => allGroups.filter(g => g.isGlobal === showGlobal),
    [allGroups, showGlobal],
  )
  const wordsList = useMemo(() => {
    if (!allWordsList) return []
    const keyword = filterKeyword.trim()
    if (keyword) {
      return allWordsList.filter(
        words =>
          !!words.items.find(word =>
            keywordCompare(keyword.toLowerCase(), stringifyWord(word).toLowerCase()),
          ),
      )
    } else {
      let result = allWordsList.filter(words => words.isGlobal === showGlobal)
      if (filterGroupId !== 'all') {
        const matchGroupId = filterGroupId === '' ? null : filterGroupId
        result = result.filter(item => item.groupId === matchGroupId)
      }
      return result
    }
  }, [allWordsList, showGlobal, filterGroupId, filterKeyword])

  return {
    showGlobal,
    setShowGlobal,
    filterGroupId,
    setFilterGroupId,
    filterKeyword,
    setFilterKeyword,

    groups,
    wordsList,
  }
}
